package cn.iocoder.yudao.module.erp.service.business.sequence;

import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.erp.controller.admin.business.sequence.vo.SequencePageReqVO;
import cn.iocoder.yudao.module.erp.controller.admin.business.sequence.vo.SequenceSaveReqVO;
import cn.iocoder.yudao.module.erp.dal.dataobject.business.sequence.SequenceDO;
import cn.iocoder.yudao.module.erp.dal.mysql.business.sequence.SequenceMapper;
import com.baomidou.lock.annotation.Lock4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.concurrent.atomic.AtomicLong;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.SEQUENCE_NOT_EXISTS;

/**
 * 单据编号 Service 实现类
 *
 * @author maxuxu
 */
@Service
@Validated
public class SequenceServiceImpl implements SequenceService {

    @Resource
    private SequenceMapper sequenceMapper;

    @Override
    public Integer createSequence(SequenceSaveReqVO createReqVO) {
        // 插入
        SequenceDO sequence = BeanUtils.toBean(createReqVO, SequenceDO.class);
        sequenceMapper.insert(sequence);
        // 返回
        return sequence.getId();
    }

    @Override
    public void updateSequence(SequenceSaveReqVO updateReqVO) {
        // 校验存在
        validateSequenceExists(updateReqVO.getId());
        // 更新
        SequenceDO updateObj = BeanUtils.toBean(updateReqVO, SequenceDO.class);
        sequenceMapper.updateById(updateObj);
    }

    @Override
    public void deleteSequence(Integer id) {
        // 校验存在
        validateSequenceExists(id);
        // 删除
        sequenceMapper.deleteById(id);
    }

    private void validateSequenceExists(Integer id) {
        if (sequenceMapper.selectById(id) == null) {
            throw exception(SEQUENCE_NOT_EXISTS);
        }
    }

    @Override
    public SequenceDO getSequence(Integer id) {
        return sequenceMapper.selectById(id);
    }

    @Override
    public PageResult<SequenceDO> getSequencePage(SequencePageReqVO pageReqVO) {
        return sequenceMapper.selectPage(pageReqVO);
    }

    @Override
    public String nextSequence() {
        // 判断是否存在

        return null;
    }
    /**
     * @param type:
      * @return String
     * @author Max-u-19
     * @description 添加了分布式锁，防止重复订单号
     * @date 2024/1/23 16:19
     */
    @Override
    @Lock4j
    public String nextSequence(String type) {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");
        LocalDateTime dateTime = LocalDateTime.now();
        String formattedDateTime = dateTime.format(formatter);
        // 判断是否存在
        SequenceDO sequenceDO = sequenceMapper.selectBySeqNamed(type);
        if (sequenceDO == null) {
            sequenceDO = SequenceDO.builder().seqName(type).seqPartition(formattedDateTime).seqNextValue(1L).build();
            sequenceMapper.insert(sequenceDO);
        }
        // 保证每天的都是从1开始计数 TODO:加定时器或者抽离出接口调用
        if (!sequenceDO.getSeqPartition().equals(formattedDateTime)) {
            sequenceDO.setSeqPartition(formattedDateTime);
            sequenceDO.setSeqNextValue(1L);
            sequenceMapper.updateById(sequenceDO);
        }
        Long seqNextValue = sequenceDO.getSeqNextValue();
        AtomicLong atomicLong = new AtomicLong(seqNextValue);
        sequenceMapper.updateById(sequenceDO.setSeqNextValue(atomicLong.incrementAndGet()));
        String nextValue = StringUtils.leftPad(String.valueOf(seqNextValue), 5, "0");
        return sequenceDO.getSeqName()+"-"+sequenceDO.getSeqPartition()+"-"+ nextValue;
    }

}